import os
import warnings

import numpy as np
import pandas as pd

from GV import *
from common.log import GetLog
from common.util import getOutPutPath

import matplotlib

matplotlib.use('Agg')
warnings.filterwarnings("ignore", category=RuntimeWarning)
from matplotlib import pyplot as plt

log = GetLog.get_logger()


class HandleLog(object):

    @staticmethod
    def clearOutPut():
        import os

        dir_path = getOutPutPath()

        # 获取目录中的文件列表
        file_list = os.listdir(dir_path)

        # 遍历文件列表并逐个删除文件
        for file_name in file_list:
            file_path = os.path.join(dir_path, file_name)
            try:
                if os.path.isfile(file_path):
                    os.remove(file_path)
                    print(f"文件 {file_path} 删除成功")
            except OSError as e:
                print(f"无法删除文件 {file_path}: {e}")

        print("所有文件删除成功")

    @staticmethod
    def clearLog():
        try:
            os.system('adb root')
            os.system('adb remount')
            os.system("adb shell rm -rf /data/anr/*")
            os.system("adb shell rm -rf /data/tombstones/*")
            os.system("adb shell rm -rf /map/user/com.mega.map/BMap/map_log/*")
            os.system("adb shell rm -rf /log/android/*")
            log.info("clear log success")
        except  Exception as e:
            log.error("clear log error")
            log.error(str(e))
        finally:
            os.system(f"adb shell am force-stop mega.map")

    @staticmethod
    def pullAnrLog():
        try:
            os.system(f'adb pull /data/anr {getOutPutPath()}')
            os.system(f'adb pull /data/tombstones {getOutPutPath()}')
        except  Exception as e:
            log.error("pull log error")
            log.error(str(e))

    @staticmethod
    def pullLog():
        try:
            os.system(f'adb pull /map/user/com.mega.map/BMap/map_log {getOutPutPath()}')
            os.system(f'adb pull /map/user/com.mega.map/BMap/InssdkLog {getOutPutPath()}')
        except  Exception as e:
            log.error("pull log error")
            log.error(str(e))


def draw_thread(thread_file, time_top):
    """
    25020 system       20   0  19G 315M 124M S  0.0   4.8   0:00.01 cpu-pool-2-thre com.mega.map
    25015 system       20   0  19G 315M 124M S  0.0   4.8   0:00.00 cpu-pool-2-thre com.mega.map
    24988 system       20   0  19G 315M 124M S  0.0   4.8   0:00.02 cpu-pool-2-thre com.mega.map
    24943 system       20   0  19G 315M 124M S  0.0   4.8   0:00.01 cpu-pool-2-thre com.mega.map
    24873 system       20   0  19G 315M 124M S  0.0   4.8   0:00.00 cpu-pool-2-thre com.mega.map
    24803 system       20   0  19G 315M 124M S  0.0   4.8   0:00.00 cpu-pool-2-thre com.mega.map
    """
    thread_dict = {}
    N = 0
    with open(thread_file) as f:
        line = f.readline()
        while line:
            thread_temp_dict = {}
            while line:

                line_list = line.strip().split()

                if line_list[-1] == "com.mega.map":
                    thread_id = line_list[-2]
                    thread_value = float(line_list[8])
                    if thread_id not in thread_temp_dict:
                        thread_temp_dict[thread_id] = [thread_value]
                    else:
                        thread_temp_dict[thread_id].append(thread_value)
                elif line_list[-1] == "PROCESS":
                    N += 1
                    line = f.readline()
                    break
                line = f.readline()

            if not thread_dict:
                for key, value in thread_temp_dict.items():
                    thread_temp_dict[key] = [sum(thread_temp_dict[key])]
                thread_dict = thread_temp_dict

            for key, value in thread_temp_dict.items():
                thread_dict[key].append(sum(thread_temp_dict[key]))

    x = np.arange(0, N + 1, 1.0)

    plt.figure(figsize=(15, 7))  # 创建一个新的图形窗口
    # 计算每个字典值的均值并保存到新字典中
    mean_dict = {key: np.mean(value) for key, value in thread_dict.items()}

    # 按照值进行排序，从高到低
    sorted_dict = dict(sorted(mean_dict.items(), key=lambda x: x[1], reverse=True))

    # 取出排序后的前五个元素
    top_five = list(sorted_dict.keys())[:5]

    for key in top_five:
        if len(thread_dict[key]) == N + 1:
            plt.plot(x, thread_dict[key], label=key + "_avg:" + str(round(mean_dict[key], 3)), linewidth=4)
    plt.legend(loc='best')
    # plt.show()
    try:
        thread_file = thread_file.replace('txt', 'png')
        plt.savefig(f"{thread_file}", dpi=400)
        log.info("draw top success")
    except  Exception as e:
        log.error("draw top failed", e)


def draw_top(top_file, time_top=['12:21:10', '12:21:27', '12:21:45', '12:22:02',
                                 '12:22:19', '12:22:36', '12:22:53', '12:23:10',
                                 '12:23:27', ], falg=True):
    """
    通过 top 画cpu res折线图
    :param top_file: top原始文件
    :param time_top: 时间点
    :return:
    """

    N = 0

    # 处理process数据
    cpu_process_list = []
    with open(top_file[0], 'r') as f:
        line = f.readline()
        while line:
            if line:
                if line.strip().split()[11] == "com.mega.map":
                    cpu_process_list.append(float(line.strip().split()[-4]))
                    N += 1
                # if len(line.strip().split()) == 12:

                line = f.readline()

    log.info(f"read top {N} processes")
    log.info(f"processes times {len(cpu_process_list)}")

    # 处理thread数据
    thread_dict = {}
    thread_error = 0
    n = 0
    with open(top_file[1], 'r') as f:
        line = f.readline()
        while line:
            thread_temp_dict = {}
            while line:
                line_list = line.strip().split()
                if line_list[-1] == "com.mega.map":
                    thread_id = line_list[-2]
                    try:
                        thread_value = float(line_list[8])
                    except Exception as e:
                        pass
                    #     continue
                    if thread_id not in thread_temp_dict:
                        thread_temp_dict[thread_id] = [thread_value]
                    else:
                        thread_temp_dict[thread_id].append(thread_value)
                elif line_list[-1] == "PROCESS":
                    line = f.readline()
                    n += 1
                    break
                line = f.readline()

            if not thread_dict:
                for key, value in thread_temp_dict.items():
                    thread_temp_dict[key] = [sum(thread_temp_dict[key])]
                thread_dict = thread_temp_dict
            else:
                for key, value in thread_temp_dict.items():
                    # print(key + ":" + str(value))
                    if sum(value) >= 100.0 * 8 or sum(value) < 0:
                        thread_error += 1
                        # print(sum(value))
                        break
                    if key in thread_dict:
                        thread_dict[key].append(sum(thread_temp_dict[key]))
                    else:
                        thread_dict[key] = thread_temp_dict[key]

    # 计算每个线程字典值的均值并保存到新字典中
    mean_dict = {key: np.mean(value) for key, value in thread_dict.items()}
    # print(mean_dict)
    df = pd.DataFrame.from_dict(mean_dict, orient='index')
    df.to_csv(top_file[1].replace("txt", "csv"), header=True)

    # 按照值进行排序，从高到低
    sorted_dict = dict(sorted(mean_dict.items(), key=lambda x: x[1], reverse=True))

    # 取出排序后的前五个元素
    top_five = list(sorted_dict.keys())[:5]

    # 校验top5的线程的数量
    for key in top_five:
        if len(thread_dict[key]) < N:
            for _ in range(N - len(thread_dict[key])):
                thread_dict[key].append(0)
        elif len(thread_dict[key]) < N:
            thread_dict[key] = thread_dict[key][0:N]

    # plt.show()

    log.info(f"read top {n} threads")
    log.info(f"threads times {len(thread_dict[top_five[0]])}")

    # 处理内存数据
    pss_dict = {}
    flag_pss = False
    m = 0
    with open(top_file[2]) as f:
        line = f.readline()
        while line:
            if " App Summary" in line:
                flag_pss = True
                m += 1
            if "Applications" in line:
                flag_pss = False
            if flag_pss:
                if ":" not in line:
                    line = f.readline()
                    continue
                pss_list = line.strip().split(":")
                key = pss_list[0]
                value = int(pss_list[1].strip().split()[0]) / 1024
                if key == "Unknown":
                    line = f.readline()
                    continue
                if key not in pss_dict:
                    pss_dict[key] = [value]
                else:
                    pss_dict[key].append(value)

            line = f.readline()
    for key, value in pss_dict.items():
        if len(value) < N:
            for _ in range(N - len(value)):
                pss_dict[key].append(0)
        elif len(value) < N:
            pss_dict[key] = pss_dict[key][0:N]

    log.info(f"read meminfo {m} Pss ")
    log.info(f"meninfo times {len(pss_dict['TOTAL PSS'])}")

    x = np.arange(0, N, 1.0)

    fig, ax = plt.subplots(2, 2, figsize=(16, 7))

    ax[0][0].plot(x, cpu_process_list, label="com.mega.map", linewidth=4)
    ax[0][0].legend(loc="upper right")

    for key in top_five:
        ax[0][1].plot(x, thread_dict[key][:N], label=key + "_avg:" + str(round(mean_dict[key], 2)), linewidth=1)
    ax[0][1].legend(loc="upper right")

    for key, value in pss_dict.items():
        ax[1][0].plot(x, value[:N], label=key, linewidth=2)
    ax[1][0].legend(loc="upper right")

    # # x轴个数
    x_label_index_list = np.linspace(0, len(time_top) - 1, num=x_Density, dtype=int)
    x_label = [time_top[i] for i in x_label_index_list]
    x_ticks = np.linspace(0, len(x) - 1, num=x_Density, dtype=int)

    ax[0][0].set_xticks(x_ticks)
    ax[0][0].set_xticklabels(x_label, rotation=90)
    ax[0][0].set_xlabel('时间点')
    ax[1][0].set_xticks(x_ticks)
    ax[1][0].set_xticklabels(x_label, rotation=90)
    ax[1][0].set_xlabel('时间点')
    ax[0][1].set_xticks(x_ticks)
    ax[0][1].set_xticklabels(x_label, rotation=90)
    ax[0][1].set_xlabel('时间点')
    ax[1][0].set_xticks(x_ticks)
    ax[1][0].set_xticklabels(x_label, rotation=90)
    ax[1][0].set_xlabel('时间点')
    # plt.show()

    # 第二行第二个子图
    cpu = [np.round(np.mean(cpu_process_list), decimals=2), np.round(np.max(cpu_process_list), decimals=2),
           np.round(np.min(cpu_process_list), decimals=2)]
    mem = [np.round(np.mean(pss_dict.get("TOTAL PSS")), decimals=2),
           np.round(np.max(pss_dict.get("TOTAL PSS")), decimals=2),
           np.round(np.min(pss_dict.get("TOTAL PSS")), decimals=2)]

    table_vals = [cpu, mem]
    col_labels = ['avg', 'max', 'min']
    row_labels = ['cpu', 'mem']
    col_colors = ['skyblue', 'skyblue', 'skyblue']
    row_colors = ['skyblue', ] * 2
    table = ax[1][1].table(cellText=table_vals, loc='center',
                           rowLabels=row_labels, colLabels=col_labels,
                           rowColours=row_colors, colColours=col_colors
                           )
    table.scale(1, 2)  # 设置表格大小为比例尺
    table.auto_set_font_size(True)  # 自动调整表格字体大小
    ax[1, 1].axis('off')
    try:
        top_file = top_file[0].replace('txt', 'png')
        plt.savefig(f"{top_file}", dpi=200)
        log.info("draw top success")
    except  Exception as e:
        log.error("draw top failed", e)


def draw_excel():
    """
    excel表格数据绘制
                avg', 'max', 'min
    cpu         0.0     0.0     0.0
     mem        0.0     0.0     0.0


    :return:
    """
    # 在CPU图片上添加值
    fig, ax = plt.subplots(2, 2, figsize=(16, 7))
    perf_data = [1, 2, 3, 4, 5, 6]
    table_vals = [[perf_data[0], perf_data[2], perf_data[4]],
                  [perf_data[0], perf_data[2], perf_data[4]], ]
    col_labels = ['avg', 'max', 'min']
    row_labels = ['cpu', 'mem']
    col_colors = ['skyblue', 'skyblue', 'skyblue']
    row_colors = ['skyblue', ] * 2
    table = ax[1][1].table(cellText=table_vals, loc='best',
                           rowLabels=row_labels, colLabels=col_labels,
                           rowColours=row_colors, colColours=col_colors
                           )
    # table.set_fontsize(15)  # 设置表格字体大小
    table.auto_set_font_size(True)
    table.scale(1, 2)
    ax[1, 1].axis('off')
    plt.show()

def draw_excel_data(data_list):
    pass


if __name__ == '__main__':
    draw_top(["top_Process_raw_752647.txt", "top_Thread_raw_752647.txt", "meminfo_Pss_raw_752647.txt"])
